﻿using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using BGShell.Interop;
using System.Drawing;

namespace BGShell.Components
{
    internal sealed class DataTipMessageFilter : IMessageFilter
    {
        private readonly DataTipForm _form;

        private DataTipMessageFilter(DataTipForm form)
        {
            _form = form;
        }

        public bool PreFilterMessage(ref Message m)
        {
            if (m.Msg == WindowMessages.WM_MOUSEMOVE)
            {
                var child = _form.TopMostTip;
                var args = MouseEventArgsFromMessage(child, m);

                child.ProcessMouseMove(args);
            }

            return false;
        }

        private static MouseEventArgs MouseEventArgsFromMessage(Control ctl, Message m)
        {
            var points = new Point[]
            {
                new Point(m.LParam.ToInt32())
            };

            NativeMethods.MapWindowPoints(
                new HandleRef(null, m.HWnd),
                new HandleRef(ctl, ctl.Handle),
                points, 1);

            return new MouseEventArgs(MouseButtons.None, 0, points[0].X, points[0].Y, 0);
        }

        internal static void BeginDataTip(DataTipForm form)
        {
            if (_instance != null)
            {
                _instance._form.Dispose();
            }

            _instance = new DataTipMessageFilter(form);
            Application.AddMessageFilter(_instance);
        }

        [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "form", Justification = "Asserted upon in DEBUG builds")]
        internal static void EndDataTip(DataTipForm form)
        {
            if (_instance != null)
            {
                Debug.Assert(_instance._form == form);
                Application.RemoveMessageFilter(_instance);
            }

            _instance = null;
        }

        [ThreadStatic]
        private static DataTipMessageFilter _instance;
    }
}
